# from flask import Flask, Response, request
# from bs4 import BeautifulSoup
# from lxml import etree
# import requests
# import hashlib
# import pytz
# import urllib
# import time
# import json
# import re
# import main
#
#
#
# def calculate_score_increase(data):
#     """
#     计算过去两周内分数的增加量，当最近两周没有比赛时，最近的分数算作两周前的分数。
#     :param data: 包含时间戳和分数的字典。
#     :param base_timestamp: 用作计算基准的时间戳。
#     :return: 一个元组，包含两周前的分数、最近的分数和增加量。
#     """
#     # 过去两周的时间范围
#     two_weeks_ago = int(time.time()) - 2 * 7 * 24 * 60 * 60
#
#     # 初始化
#     latest_score_within_two_weeks = None
#     latest_score_before_two_weeks = None
#     last_score = None  # 记录最后一次的分数
#
#     # 遍历数据，寻找在指定时间范围内的分数
#     for timestamp_str, score in sorted(data.items(), key=lambda item: int(item[0])):
#         timestamp = int(timestamp_str)
#         last_score = score  # 更新最后一次的分数
#
#         # 如果在过去两周内
#         if timestamp >= two_weeks_ago:
#             latest_score_within_two_weeks = score
#         else:
#             latest_score_before_two_weeks = score
#
#     # 计算增加量
#     if latest_score_within_two_weeks is not None:
#         if latest_score_before_two_weeks is not None:
#             increase = latest_score_within_two_weeks - latest_score_before_two_weeks
#         else:
#             increase = latest_score_within_two_weeks  # 只有近两周打过比赛
#     else:
#         increase = 0  # 近两周没有分数
#         # 当两周前有比赛而最近两周没有比赛时，最近的分数算作两周前的分数
#         latest_score_within_two_weeks = last_score
#
#     return (
#         latest_score_before_two_weeks or 0,
#         latest_score_within_two_weeks or 0,
#         increase,
#     )
#
#
# def delete_zero(n):
#     """删除小数点后多余的0"""
#     n = "{:g}".format(n)
#     n = float(n) if "." in n else int(n)  # 含小数点转float否则int
#     return n
#
#
# def get_at_race():
#     url = "https://atcoder.jp/contests/"
#     response = requests.get(url)
#     web_content = response.content
#     soup = BeautifulSoup(web_content, "html.parser")
#     upcoming_contests = soup.find("div", id="contest-table-upcoming")
#     contests = upcoming_contests.find_all("tr")[1:]
#     race_dict = []
#     for contest in contests:
#         columns = contest.find_all("td")
#         contest_time = columns[0].text.strip()  # 比赛时间
#         given_time = contest_time
#         given_format = "%Y-%m-%d %H:%M:%S%z"
#         dt_given = datetime.strptime(given_time, given_format)
#         beijing_tz = pytz.timezone("Asia/Shanghai")
#         contest_time = int(dt_given.astimezone(beijing_tz).timestamp())
#         contest_name = columns[1].text.strip()  # 比赛名称
#         contest_name = re.sub(".+\\n|.+\\t|\\t|\\n", "", contest_name)
#         contest_duration = columns[2].text.strip()  # 比赛持续时间
#         race_dict.append([contest_time, contest_name, contest_duration])
#     return race_dict
#
#
# def get_lq_race():
#     url = "https://www.lanqiao.cn/api/v2/contests/?sort=opentime&paginate=0&status=not_finished&game_type_code=2"
#     resp = requests.get(url).json()
#     race_dict = []
#     for i in resp:
#         race_name = i["name"]
#         open_at = datetime.fromisoformat(i["open_at"]).timestamp()
#         o = re.sub("(\+08:00|T)", " ", i["open_at"])
#         end_at = datetime.fromisoformat(i["end_at"]).timestamp()
#         e = re.sub("(\+08:00|T)", " ", i["end_at"])
#         seconds = int(end_at - open_at)
#         hours, remainder = divmod(seconds, 3600)
#         minutes, _ = divmod(remainder, 60)
#         formatted_time = f"{hours:02}:{minutes:02}"
#         race_dict.append([int(open_at), race_name, formatted_time])
#     return race_dict
#
#
# def get_cf_race():
#     resp = requests.get("https://codeforces.com/api/contest.list").json()["result"]
#     race_dict = []
#     for i in resp:
#         if i["phase"] == "BEFORE":
#             seconds = int(i["durationSeconds"])
#             hours, remainder = divmod(seconds, 3600)
#             minutes, _ = divmod(remainder, 60)
#             formatted_time = f"{hours:02}:{minutes:02}"
#             race_dict.append([int(i["startTimeSeconds"]), i["name"], formatted_time])
#     return race_dict
#
#
# def get_nk_race():
#     resp = requests.get("https://ac.nowcoder.com/acm/contest/vip-index").text
#     resp = etree.HTML(resp)
#     resp = resp.xpath("//html/body/div[1]/div[3]/div[1]/div[2]")
#     resp = etree.HTML(etree.tostring(resp[0], pretty_print=True).decode())
#     resp = resp.xpath("//div[@class='platform-item js-item ']")
#     race_dict = []
#     for i in resp:
#         place = etree.HTML(etree.tostring(i, pretty_print=True).decode())
#         race_name = place.xpath("//div[2]/div[1]/h4/a[1]/text()")[0]
#         text = place.xpath("//div[2]/div[1]/ul/li/text()")[1]
#         start_time_match = re.search(r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2})", text)
#         end_time_match = re.findall(r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2})", text)[1]
#         start_time_dt = datetime.strptime(start_time_match.group(0), "%Y-%m-%d %H:%M")
#         end_time_dt = datetime.strptime(end_time_match, "%Y-%m-%d %H:%M")
#         duration = end_time_dt - start_time_dt
#         start_timestamp = start_time_dt.timestamp()
#         end_timestamp = end_time_dt.timestamp()
#         seconds = int(end_timestamp - start_timestamp)
#         hours, remainder = divmod(seconds, 3600)
#         minutes, _ = divmod(remainder, 60)
#         formatted_time = f"{hours:02}:{minutes:02}"
#         race_dict.append([int(start_timestamp), race_name, formatted_time])
#     return race_dict
#
#
# def get_lg_race():
#     headers = {
#         "cookie": "_uid=0; __client_id=308d0bf229a0b62ed3d9b3371d499207ed592d3a",
#         "Referer": "https://www.luogu.com.cn/",
#         "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0",
#     }
#     resp = requests.get("https://www.luogu.com.cn/contest/list", headers=headers).text
#     resp = re.search(r'JSON\.parse\(decodeURIComponent\("([^"]+)"\)\)', resp).group(1)
#     race_dict = []
#     for i in json.loads(urllib.parse.unquote(resp))["currentData"]["contests"][
#                  "result"
#              ][::-1]:
#         if i["startTime"] >= time.time():
#             seconds = int(i["endTime"] - i["startTime"])
#             hours, remainder = divmod(seconds, 3600)
#             minutes, _ = divmod(remainder, 60)
#             formatted_time = f"{hours:02}:{minutes:02}"
#             race_dict.append([int(i["startTime"]), i["name"], formatted_time])
#     return race_dict
#
#
# def get_acm_race():
#     cf_race = get_cf_race()
#     for key, i in enumerate(cf_race):
#         cf_race[key][1] = "(codeforces)" + cf_race[key][1]
#     at_race = get_at_race()
#     for key, i in enumerate(at_race):
#         at_race[key][1] = "(atcoder)" + at_race[key][1]
#     lq_race = get_lq_race()
#     for key, i in enumerate(lq_race):
#         lq_race[key][1] = "(蓝桥杯)" + lq_race[key][1]
#     nk_race = get_nk_race()
#     for key, i in enumerate(nk_race):
#         nk_race[key][1] = "(牛客)" + nk_race[key][1]
#     lg_race = get_lg_race()
#     for key, i in enumerate(lg_race):
#         lg_race[key][1] = "(洛谷)" + lg_race[key][1]
#     all_races = cf_race + at_race + lq_race + nk_race + lg_race
#     sorted_races = sorted(all_races, key=lambda x: x[0])
#     new_sorted_races = []
#     for i in sorted_races:
#         if i[0] - time.time() <= 14 * 24 * 3600:
#             new_sorted_races.append(i)
#     return new_sorted_races
#
#
# @app.route("/<string:web_name>_race")
# def web_race(web_name):
#     if web_name == "cf":
#         race_dict = get_cf_race()[::-1]
#     if web_name == "at":
#         race_dict = get_at_race()
#     if web_name == "lq":
#         race_dict = get_lq_race()
#     if web_name == "nk":
#         race_dict = get_nk_race()
#     if web_name == "lg":
#         race_dict = get_lg_race()
#     if web_name == "acm":
#         race_dict = get_acm_race()
#     answer = ""
#     for i in race_dict:
#         race_time = datetime.fromtimestamp(i[0]).strftime("%Y-%m-%d %H:%M")
#         answer += f"{i[1]}\n比赛时间:{race_time}\n比赛时长:{i[2]}\n\n"
#     return answer
#
#
# def cf_get_data(cf_name):
#     user_data = requests.get(f"https://codeforces.com/profile/{cf_name}").text
#     if re.search("Can\\'t find such user", user_data):
#         return None
#     if not re.findall(
#             '<span style="font-weight:bold;" class="user-\w+">(\d+)</span>', user_data
#     ):
#         return {}
#     user_score_list = re.findall("unrated\.push\(\[\d+, \d+,  \d+\]\);", user_data)
#     cf_data = {}
#     for i in user_score_list:
#         data = re.findall("unrated\.push\(\[(\d+), (\d+),  (\d+)\]\);", i)
#         cf_data.update({int(str(int(data[0][0]))[:10]): int(data[0][1])})
#     return cf_data
#
#
# @app.route("/cf_bd", methods=["POST"])
# def cf_bd():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     cf_data = cf_get_data(user_name)
#     if cf_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if Acm_data.query.filter(Acm_data.cf_name == user_name).first() is not None:
#         return "该CF号已被绑定,暂不支持绑定"
#     acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#     if acm_data is None:
#         db.session.add(Acm_data(qq=user_qq))
#         db.session.commit()
#     if int(max(list(cf_data.values()) + [0])) > 2500:
#         return "该CF号Rating过高,暂不支持绑定"
#     up_dict = {"cf_name": user_name, "cf_data": json.dumps(cf_data)}
#     Acm_data.query.filter(Acm_data.QQ == user_qq).update(up_dict)
#     db.session.commit()
#     return "绑定成功"
#
#
# @app.route("/cf_list_refresh")
# def cf_list_refresh():
#     results = Acm_data.query.filter(Acm_data.cf_name.isnot(None)).all()
#     qq_list = []
#     for result in results:
#         qq_list.append(result.QQ)
#     for i in qq_list:
#         data = Acm_data.query.filter(Acm_data.QQ == i).first()
#         cf_data = cf_get_data(data.cf_name)
#         up_dict = {"cf_data": json.dumps(cf_data)}
#         Acm_data.query.filter(Acm_data.QQ == i).update(up_dict)
#         db.session.commit()
#     print("cf数据更新成功")
#     return ""
#
#
# @app.route("/cf_search", methods=["POST"])
# def cf_search():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     if user_name == "" and user_qq != "":
#         acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#         if acm_data is None:
#             return "该QQ未绑定CF账号\n发送绑定cf 你的cf号以绑定\n(例:绑定cf 7355608)"
#         else:
#             if acm_data.cf_name is None:
#                 return (
#                     "该QQ未绑定CF账号\n发送绑定cf 你的cf号以绑定\n(例:绑定cf 7355608)"
#                 )
#             user_name = acm_data.cf_name
#     cf_data = cf_get_data(user_name)
#     if Acm_data.query.filter(Acm_data.cf_name == user_name).first() is not None:
#         if (
#                 Acm_data.query.filter(
#                     Acm_data.cf_name == user_name, Acm_data.cf_data == json.dumps(cf_data)
#                 ).first()
#                 is None
#         ):
#             try:
#                 requests.get("http://192.168.0.31:2433/cf_list_refresh", timeout=0.1)
#             except:
#                 pass
#     if cf_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if cf_data == {}:
#         return f"name:{user_name}\nnow:0\nmax:0\n"
#     now_score = int(list(cf_data.values())[-1])
#     max_score = int(max(list(cf_data.values())))
#     png_name = rating2photo(list(cf_data.keys()), list(cf_data.values()))
#     return f"name:{user_name}\nnow:{now_score}\nmax:{max_score}\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#
#
# @app.route("/cf_list", methods=["POST"])
# def cf_list():
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list), Acm_data.cf_data != "{}"
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.cf_data != "{}",
#             Acm_data.year == str(spilt_year),
#         ).all()
#     for key, result in enumerate(results):
#         rating = json.loads(result.cf_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].cf_name}\\n    {qq_score[i][1]}分\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].cf_name}\\n    {qq_score[i][1]}分\\n"
#     return answer
#
#
# @app.route("/cf_list_mine/<mine_qq>", methods=["POST"])
# def cf_list_mine(mine_qq):
#     mine_qq = str(mine_qq)
#     acm_data = Acm_data.query.filter(Acm_data.QQ == mine_qq).first()
#     if acm_data is None:
#         return "该QQ未绑定CF账号\\n发送绑定cf 你的cf号以绑定\\n(例:绑定cf 7355608)"
#     if acm_data.cf_name is None:
#         return "该QQ未绑定CF账号\\n发送绑定cf 你的cf号以绑定\\n(例:绑定cf 7355608)"
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.cf_data != "{}"
#     ).all()
#     qq_score = {}
#     for key, result in enumerate(results):
#         rating = json.loads(result.cf_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     for i in range(len(qq_score)):
#         if results[qq_score[i][0]].QQ == mine_qq:
#             answer += f"你的CF分数为{qq_score[i][1]}分\\nCF排名为第{i + 1}名\\n(群内共{len(qq_score)}人已绑定CF)"
#             break
#     else:
#         answer += f"你的CF分数为{0}分\\nCF排名为第{len(qq_score)}名\\n(群内共{len(qq_score)}人已绑定CF)"
#     return answer
#
#
# @app.route("/cf_times/<int:real_name>", methods=["POST"])
# def cf_times(real_name):
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.cf_data != "{}"
#     ).all()
#     now_time = time.time()
#     test_time = now_time - 14 * 24 * 3600
#     cf_time_dict = {
#         0: [],
#         1: [],
#         2: [],
#         3: [],
#         4: [],
#         5: [],
#         6: [],
#         7: [],
#         8: [],
#         9: [],
#         10: [],
#         11: [],
#         12: [],
#         13: [],
#         14: [],
#         15: [],
#         16: [],
#     }
#     for result in results:
#         cf_data = json.loads(result.cf_data)
#         cf_time = 0
#         for do_time in list(cf_data.keys())[::-1]:
#             if int(do_time) >= test_time:
#                 cf_time += 1
#             else:
#                 break
#         cf_time_dict[cf_time] = cf_time_dict[cf_time] + [result.QQ]
#     answer = ""
#     for times in range(16, -1, -1):
#         qq_list = cf_time_dict[times]
#         if qq_list != []:
#             if real_name == 1:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 results = Acm_data.query.filter(Acm_data.QQ.in_(qq_list)).all()
#                 length = 0
#                 for result in results:
#                     if len(result.user_name) == 2:
#                         answer += f"{result.user_name}      "
#                     else:
#                         answer += f"{result.user_name}  "
#                     length += 1
#                     if length == 4:
#                         length = 0
#                         answer += "\\n"
#                 if length != 0:
#                     answer += "\\n\\n"
#                 else:
#                     answer += "\\n"
#             else:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 for qq in qq_list:
#                     answer += f"$群昵称 %群号% {qq}$\\n"
#                 answer += "\\n"
#     return answer
#
#
# @app.route("/cf_add_list/<int:zf>", methods=["POST"])
# def cf_add_list(zf):
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     qq_score_o_n = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list), Acm_data.cf_data != "{}"
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.cf_data != "{}",
#             Acm_data.year == str(spilt_year),
#         ).all()
#
#     for key, result in enumerate(results):
#         rating = json.loads(result.cf_data)
#         o, n, inc = calculate_score_increase(rating)
#         qq_score.update({key: inc})
#         qq_score_o_n.update({key: [o, n]})
#     if zf == 1:
#         reverse = True
#     else:
#         reverse = False
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=reverse)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].cf_name}\\n    变化{qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].cf_name}\\n    {qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     return answer
#
#
# def at_get_data(at_name):
#     user_data = requests.get(f"https://atcoder.jp/users/{at_name}?graph=rating").text
#     if re.search(" User not found\.", user_data):
#         return None
#     user_data = etree.HTML(user_data)
#     user_data = user_data.xpath('//*[@id="main-container"]/div[1]/div[3]/div/script[2]')
#     try:
#         user_data = etree.tostring(user_data[0], pretty_print=True).decode()
#     except IndexError:
#         return {}
#     user_data = re.sub("<script>var rating_history=|;</script>", "", user_data)
#     rating_history_json = json.loads(user_data)
#     at_data = {}
#     for i in rating_history_json:
#         at_data.update({int(str(int(i["EndTime"]))[:10]): i["NewRating"]})
#     return at_data
#
#
# @app.route("/at_bd", methods=["POST"])
# def at_bd():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     at_data = at_get_data(user_name)
#     if at_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if Acm_data.query.filter(Acm_data.at_name == user_name).first() is not None:
#         return "该AT号已被绑定,暂不支持绑定"
#     acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#     if acm_data is None:
#         db.session.add(Acm_data(qq=user_qq))
#         db.session.commit()
#     if int(max(list(at_data.values()) + [0])) > 2500:
#         return "该AT号Rating过高,暂不支持绑定"
#     up_dict = {"at_name": user_name, "at_data": json.dumps(at_data)}
#     Acm_data.query.filter(Acm_data.QQ == user_qq).update(up_dict)
#     db.session.commit()
#     return "绑定成功"
#
#
# @app.route("/at_list_refresh")
# def at_list_refresh():
#     results = Acm_data.query.filter(Acm_data.at_name.isnot(None)).all()
#     qq_list = []
#     for result in results:
#         qq_list.append(result.QQ)
#     for i in qq_list:
#         data = Acm_data.query.filter(Acm_data.QQ == i).first()
#         at_data = at_get_data(data.at_name)
#         up_dict = {"at_data": json.dumps(at_data)}
#         Acm_data.query.filter(Acm_data.QQ == i).update(up_dict)
#         db.session.commit()
#     print("at数据更新成功")
#     return ""
#
#
# @app.route("/at_search", methods=["POST"])
# def at_search():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     if user_name == "" and user_qq != "":
#         acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#         if acm_data is None:
#             return "该QQ未绑定AT账号\n发送绑定at 你的at号以绑定\n(例:绑定at 7355608)"
#         else:
#             if acm_data.at_name is None:
#                 return (
#                     "该QQ未绑定AT账号\n发送绑定at 你的at号以绑定\n(例:绑定at 7355608)"
#                 )
#             user_name = acm_data.at_name
#     at_data = at_get_data(user_name)
#     if Acm_data.query.filter(Acm_data.at_name == user_name).first() is not None:
#         if (
#                 Acm_data.query.filter(
#                     Acm_data.at_name == user_name, Acm_data.at_data == json.dumps(at_data)
#                 ).first()
#                 is None
#         ):
#             try:
#                 requests.get("http://192.168.0.31:2433/at_list_refresh", timeout=0.1)
#             except:
#                 pass
#     if at_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if at_data == {}:
#         return f"name:{user_name}\nnow:0\nmax:0\n"
#     now_score = int(list(at_data.values())[-1])
#     max_score = int(max(list(at_data.values())))
#     png_name = rating2photo(list(at_data.keys()), list(at_data.values()))
#     return f"name:{user_name}\nnow:{now_score}\nmax:{max_score}\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#
#
# @app.route("/at_list", methods=["POST"])
# def at_list():
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list), Acm_data.at_data != "{}"
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.at_data != "{}",
#             Acm_data.year == str(spilt_year),
#         ).all()
#     for key, result in enumerate(results):
#         rating = json.loads(result.at_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].at_name}\\n    {qq_score[i][1]}分\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].at_name}\\n    {qq_score[i][1]}分\\n"
#     return answer
#
#
# @app.route("/at_list_mine/<mine_qq>", methods=["POST"])
# def at_list_mine(mine_qq):
#     mine_qq = str(mine_qq)
#     acm_data = Acm_data.query.filter(Acm_data.QQ == mine_qq).first()
#     if acm_data is None:
#         return "该QQ未绑定AT账号\\n发送绑定at 你的at号以绑定\\n(例:绑定at 7355608)"
#     if acm_data.at_name is None:
#         return "该QQ未绑定AT账号\\n发送绑定at 你的at号以绑定\\n(例:绑定at 7355608)"
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.at_data != "{}"
#     ).all()
#     qq_score = {}
#     for key, result in enumerate(results):
#         rating = json.loads(result.at_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     for i in range(len(qq_score)):
#         if results[qq_score[i][0]].QQ == mine_qq:
#             answer += f"你的AT分数为{qq_score[i][1]}分\\nAT排名为第{i + 1}名\\n(群内共{len(qq_score)}人已绑定AT)"
#             break
#     else:
#         answer += f"你的AT分数为{0}分\\nAT排名为第{len(qq_score)}名\\n(群内共{len(qq_score)}人已绑定AT)"
#     return answer
#
#
# @app.route("/at_add_list/<int:zf>", methods=["POST"])
# def at_add_list(zf):
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     qq_score_o_n = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list), Acm_data.at_data != "{}"
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.at_data != "{}",
#             Acm_data.year == str(spilt_year),
#         ).all()
#
#     for key, result in enumerate(results):
#         rating = json.loads(result.at_data)
#         o, n, inc = calculate_score_increase(rating)
#         qq_score.update({key: inc})
#         qq_score_o_n.update({key: [o, n]})
#     if zf == 1:
#         reverse = True
#     else:
#         reverse = False
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=reverse)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].at_name}\\n    变化{qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].at_name}\\n    {qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     return answer
#
#
# @app.route("/at_times/<int:real_name>", methods=["POST"])
# def at_times(real_name):
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.at_data != "{}"
#     ).all()
#     now_time = time.time()
#     test_time = now_time - 14 * 24 * 3600
#     at_time_dict = {
#         0: [],
#         1: [],
#         2: [],
#         3: [],
#         4: [],
#         5: [],
#         6: [],
#         7: [],
#         8: [],
#         9: [],
#         10: [],
#         11: [],
#         12: [],
#         13: [],
#         14: [],
#         15: [],
#         16: [],
#     }
#     for result in results:
#         at_data = json.loads(result.at_data)
#         at_time = 0
#         for do_time in list(at_data.keys())[::-1]:
#             if int(do_time) >= test_time:
#                 at_time += 1
#             else:
#                 break
#         at_time_dict[at_time] = at_time_dict[at_time] + [result.QQ]
#     answer = ""
#     for times in range(16, -1, -1):
#         qq_list = at_time_dict[times]
#         if qq_list != []:
#             if real_name == 1:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 results = Acm_data.query.filter(Acm_data.QQ.in_(qq_list)).all()
#                 length = 0
#                 for result in results:
#                     if len(result.user_name) == 2:
#                         answer += f"{result.user_name}      "
#                     else:
#                         answer += f"{result.user_name}  "
#                     length += 1
#                     if length == 4:
#                         length = 0
#                         answer += "\\n"
#                 if length != 0:
#                     answer += "\\n\\n"
#                 else:
#                     answer += "\\n"
#             else:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 for qq in qq_list:
#                     answer += f"$群昵称 %群号% {qq}$\\n"
#                 answer += "\\n"
#     return answer
#
#
# def nk_get_data(nk_name):
#     url = f"https://gw-c.nowcoder.com/api/sparta/pc/search"
#     resp = requests.post(
#         url,
#         data=json.dumps({"query": nk_name, "type": "user"}),
#         headers={"Content-Type": "application/json"},
#     ).json()
#     resp = resp["data"]["records"]
#     for i in resp:
#         if i["nickname"] == nk_name:
#             url = f"https://ac.nowcoder.com/acm/contest/rating-history?token=&uid={i['userId']}&_={int(time.time() * 1000 // 1)}"
#             data = requests.get(url).json()["data"]
#             nk_data = {}
#             for j in data:
#                 nk_data.update({int(str(int(j["time"]))[:10]): int(j["rating"])})
#             if nk_data != {}:
#                 return nk_data
#         else:
#             return None
#
#
# @app.route("/nk_bd", methods=["POST"])
# def nk_bd():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     nk_data = nk_get_data(user_name)
#     print(user_name, nk_data)
#     if nk_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if Acm_data.query.filter(Acm_data.nk_name == user_name).first() is not None:
#         return "该牛客号已被绑定,暂不支持绑定"
#     acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#     if acm_data is None:
#         db.session.add(Acm_data(qq=user_qq))
#         db.session.commit()
#     if int(max(list(nk_data.values()) + [0])) > 2500:
#         return "该牛客号Rating过高,暂不支持绑定"
#     up_dict = {"nk_name": user_name, "nk_data": json.dumps(nk_data)}
#     Acm_data.query.filter(Acm_data.QQ == user_qq).update(up_dict)
#     db.session.commit()
#     return "绑定成功"
#
#
# @app.route("/nk_list_refresh")
# def nk_list_refresh():
#     results = Acm_data.query.filter(Acm_data.nk_name.isnot(None)).all()
#     qq_list = []
#     for result in results:
#         qq_list.append(result.QQ)
#     for i in qq_list:
#         data = Acm_data.query.filter(Acm_data.QQ == i).first()
#         nk_data = nk_get_data(data.nk_name)
#         if nk_data is not None:
#             up_dict = {"nk_data": json.dumps(nk_data)}
#             Acm_data.query.filter(Acm_data.QQ == i).update(up_dict)
#             db.session.commit()
#     print("牛客数据更新成功")
#     return ""
#
#
# @app.route("/nk_search", methods=["POST"])
# def nk_search():
#     user_name = str(request.form["user_name"])
#     user_qq = str(request.form["user_qq"])
#     if user_name == "" and user_qq != "":
#         acm_data = Acm_data.query.filter(Acm_data.QQ == user_qq).first()
#         if acm_data is None:
#             return "该QQ未绑定牛客账号\n发送绑定nk 你的nk号以绑定\n(例:绑定nk 7355608)"
#         else:
#             if acm_data.nk_name is None:
#                 return (
#                     "该QQ未绑定牛客账号\n发送绑定nk 你的nk号以绑定\n(例:绑定nk 7355608)"
#                 )
#             user_name = acm_data.nk_name
#     nk_data = nk_get_data(user_name)
#     if Acm_data.query.filter(Acm_data.nk_name == user_name).first() is not None:
#         if (
#                 Acm_data.query.filter(
#                     Acm_data.nk_name == user_name, Acm_data.nk_data == json.dumps(nk_data)
#                 ).first()
#                 is None
#         ):
#             try:
#                 requests.get("http://192.168.0.31:2433/nk_list_refresh", timeout=0.1)
#             except:
#                 pass
#     if nk_data == None:
#         return f"未找到有关{user_name}的信息\n"
#     if nk_data == {}:
#         return f"name:{user_name}\nnow:0\nmax:0\n"
#     now_score = int(list(nk_data.values())[-1])
#     max_score = int(max(list(nk_data.values())))
#     png_name = rating2photo(list(nk_data.keys()), list(nk_data.values()))
#     return f"name:{user_name}\nnow:{now_score}\nmax:{max_score}\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#
#
# @app.route("/nk_list", methods=["POST"])
# def nk_list():
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.nk_data != "{}",
#             Acm_data.nk_data.isnot(None),
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.nk_data != "{}",
#             Acm_data.nk_data.isnot(None),
#             Acm_data.year == str(spilt_year),
#         ).all()
#     for key, result in enumerate(results):
#         rating = json.loads(result.nk_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].nk_name}\\n    {qq_score[i][1]}分\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].nk_name}\\n    {qq_score[i][1]}分\\n"
#     return answer
#
#
# @app.route("/nk_list_mine/<mine_qq>", methods=["POST"])
# def nk_list_mine(mine_qq):
#     mine_qq = str(mine_qq)
#     acm_data = Acm_data.query.filter(Acm_data.QQ == mine_qq).first()
#     if acm_data is None:
#         return "该QQ未绑定牛客账号\\n发送绑定nk 你的牛客号以绑定\\n(例:绑定nk 7355608)"
#     if acm_data.nk_name is None:
#         return "该QQ未绑定牛客账号\\n发送绑定nk 你的牛客号以绑定\\n(例:绑定nk 7355608)"
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.nk_data != "{}"
#     ).all()
#     qq_score = {}
#     for key, result in enumerate(results):
#         rating = json.loads(result.nk_data)
#         qq_score.update({key: rating[list(rating.keys())[-1]]})
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
#     answer = ""
#     for i in range(len(qq_score)):
#         if results[qq_score[i][0]].QQ == mine_qq:
#             answer += f"你的牛客分数为{qq_score[i][1]}分\\n牛客排名为第{i + 1}名\\n(群内共{len(qq_score)}人已绑定牛客)"
#             break
#     else:
#         answer += f"你的牛客分数为{0}分\\n牛客排名为第{len(qq_score)}名\\n(群内共{len(qq_score)}人已绑定CF)"
#     return answer
#
#
# @app.route("/nk_times/<int:real_name>", methods=["POST"])
# def nk_times(real_name):
#     group_list = json.loads(str(request.form["group_list"]))
#     results = Acm_data.query.filter(
#         Acm_data.QQ.in_(group_list), Acm_data.nk_data != "{}"
#     ).all()
#     now_time = time.time()
#     test_time = now_time - 14 * 24 * 3600
#     nk_time_dict = {
#         0: [],
#         1: [],
#         2: [],
#         3: [],
#         4: [],
#         5: [],
#         6: [],
#         7: [],
#         8: [],
#         9: [],
#         10: [],
#         11: [],
#         12: [],
#         13: [],
#         14: [],
#         15: [],
#         16: [],
#     }
#     for result in results:
#         nk_data = json.loads(result.nk_data)
#         nk_time = 0
#         for do_time in list(nk_data.keys())[::-1]:
#             if int(do_time) >= test_time:
#                 nk_time += 1
#             else:
#                 break
#         nk_time_dict[nk_time] = nk_time_dict[nk_time] + [result.QQ]
#     answer = ""
#     for times in range(16, -1, -1):
#         qq_list = nk_time_dict[times]
#         if qq_list != []:
#             if real_name == 1:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 results = Acm_data.query.filter(Acm_data.QQ.in_(qq_list)).all()
#                 length = 0
#                 for result in results:
#                     if len(result.user_name) == 2:
#                         answer += f"{result.user_name}      "
#                     else:
#                         answer += f"{result.user_name}  "
#                     length += 1
#                     if length == 4:
#                         length = 0
#                         answer += "\\n"
#                 if length != 0:
#                     answer += "\\n\\n"
#                 else:
#                     answer += "\\n"
#             else:
#                 answer += f"近2周共参加{times}场的有:\\n"
#                 for qq in qq_list:
#                     answer += f"$群昵称 %群号% {qq}$\\n"
#                 answer += "\\n"
#     return answer
#
#
# @app.route("/nk_add_list/<int:zf>", methods=["POST"])
# def nk_add_list(zf):
#     group_list = json.loads(str(request.form["group_list"]))
#     len_list = int(request.form["len_list"])
#     real_name = int(request.form["real_name"])
#     spilt_year = int(request.form["spilt_year"])
#     qq_score = {}
#     qq_score_o_n = {}
#     if spilt_year == 0:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list), Acm_data.nk_data != "{}"
#         ).all()
#     else:
#         results = Acm_data.query.filter(
#             Acm_data.QQ.in_(group_list),
#             Acm_data.nk_data != "{}",
#             Acm_data.year == str(spilt_year),
#         ).all()
#
#     for key, result in enumerate(results):
#         rating = json.loads(result.nk_data)
#         o, n, inc = calculate_score_increase(rating)
#         qq_score.update({key: inc})
#         qq_score_o_n.update({key: [o, n]})
#     if zf == 1:
#         reverse = True
#     else:
#         reverse = False
#     qq_score = sorted(qq_score.items(), key=lambda kv: (kv[1], kv[0]), reverse=reverse)
#     answer = ""
#     if real_name == 0:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 answer += f"第{i + 1}名：$群昵称 %群号% {results[qq_score[i][0]].QQ}$\\n      {results[qq_score[i][0]].nk_name}\\n    变化{qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     else:
#         for i in range(len(qq_score)):
#             if i < len_list:
#                 if results[qq_score[i][0]].user_name is None:
#                     name = f"{results[qq_score[i][0]].QQ}此人未绑定真实姓名"
#                 else:
#                     name = results[qq_score[i][0]].user_name
#                 answer += f"第{i + 1}名：{name}\\n      {results[qq_score[i][0]].nk_name}\\n    {qq_score[i][1]}分({qq_score_o_n[qq_score[i][0]][0]}->{qq_score_o_n[qq_score[i][0]][1]})\\n"
#     return answer
#
#
# @app.route("/acm_hot_one/<string:qq>/<int:real_name>")
# def acm_hot_one(qq, real_name):
#     result = Acm_data.query.filter(Acm_data.QQ == qq).first()
#     if result is None:
#         return "该QQ未绑定任何账号"
#     if result.cf_name is None and result.at_name is None and result.nk_name is None:
#         return "该QQ未绑定任何账号"
#     cf_race_data = {}
#     if result.cf_name is not None:
#         cf_data = json.loads(result.cf_data)
#         for time_t, rating in cf_data.items():
#             if int(time_t) >= time.time() - 14 * 24 * 3600:
#                 cf_race_data.update({time_t: rating})
#     at_race_data = {}
#     if result.at_name is not None:
#         at_data = json.loads(result.at_data)
#         for time_t, rating in at_data.items():
#             if int(time_t) >= time.time() - 14 * 24 * 3600:
#                 at_race_data.update({time_t: rating})
#     nk_race_data = {}
#     if result.nk_name is not None:
#         nk_data = json.loads(result.nk_data)
#         for time_t, rating in nk_data.items():
#             if int(time_t) >= time.time() - 14 * 24 * 3600:
#                 nk_race_data.update({time_t: rating})
#     cf_times = len(cf_race_data)
#     at_times = len(at_race_data)
#     nk_times = len(nk_race_data)
#     all_times = cf_times + at_times + nk_times
#     answer = ""
#     if real_name == 0:
#         answer += f"$群昵称 %群号% {qq}$,你好啊\\n"
#     if real_name == 1:
#         if result.user_name is None:
#             answer += "该QQ未绑定真实姓名"
#         else:
#             answer += f"{result.user_name},你好啊\\n"
#     answer += f"过去两周你共参加{all_times}场比赛\\n其中CF {cf_times}场,AT {at_times}场,牛客 {at_times}场\\n"
#     if cf_times != 0:
#         max_cf_rating = max(list(cf_race_data.values()))
#         min_cf_rating = min(list(cf_race_data.values()))
#         now_cf_rating = list(cf_race_data.values())[-1]
#         png_name = rating2photo_bar(
#             list(map(int, list(cf_race_data.keys()))), list(cf_race_data.values())
#         )
#         answer += f"期间CF最高Rating为{max_cf_rating}\\n最低为{min_cf_rating}\\n最近的一次Rating为{now_cf_rating}\\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#     if at_times != 0:
#         max_at_rating = max(list(at_race_data.values()))
#         min_at_rating = min(list(at_race_data.values()))
#         now_at_rating = list(at_race_data.values())[-1]
#         png_name = rating2photo_bar(
#             list(map(int, list(at_race_data.keys()))), list(at_race_data.values())
#         )
#         answer += f"期间AT最高Rating为{max_at_rating}\\n最低为{min_at_rating}\\n最近的一次Rating为{now_at_rating}\\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#     if nk_times != 0:
#         max_nk_rating = max(list(nk_race_data.values()))
#         min_nk_rating = min(list(nk_race_data.values()))
#         now_nk_rating = list(nk_race_data.values())[-1]
#         png_name = rating2photo_bar(
#             list(map(int, list(nk_race_data.keys()))), list(nk_race_data.values())
#         )
#         answer += f"期间牛客最高Rating为{max_nk_rating}\\n最低为{min_nk_rating}\\n最近的一次Rating为{now_nk_rating}\\n±img=http://192.168.0.31:2433/acm_photo/{png_name}±"
#
#     return answer
#
#
# app.run(host="0.0.0.0", port=2433, threaded=True)
